package com.linkoog.devtools.json.file_editer.editer;

import com.intellij.json.JsonFileType;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.util.LocalTimeCounter;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.JBDimension;
import com.linkoog.devtools.json.file_editer.editer.ui.JsonEditerRightPanel;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.List;

/**
 *    在 json编辑器上，注入额外的panel面板。
 */
public class JsonEditerPanelInjector implements FileEditorManagerListener, BulkFileListener {

    private final Project project;

    public static final Key<JsonEditerRightPanel> KEY_JSON_EDITER_RIGHT_PANEL = new Key<>("JsonEditerRightPanel");

    public JsonEditerPanelInjector(@NotNull Project project){
        this.project = project;
        MessageBusConnection messageBusConnection = project.getMessageBus().connect(project);
        messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, this);
        messageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
    }




    /**
     *   文件打开后，注入右侧可视化面板
     */
    @Override
    public void fileOpened(@NotNull FileEditorManager fileEditorManager, @NotNull VirtualFile virtualFile) {
        if (!(virtualFile.getFileType() instanceof JsonFileType)){
            return;
        }


        ActionManager actionManager = ActionManager.getInstance();
        FileEditor[] fileEditors = fileEditorManager.getEditors(virtualFile);
        for (FileEditor fileEditor : fileEditors) {
            if (!(fileEditor instanceof TextEditor)){
                continue;
            }

            TextEditor textEditor = (TextEditor) fileEditor;
            JComponent editerComponent = fileEditor.getComponent();
            Container editerParentComponent = editerComponent.getParent();

            JPanel containerPanel = null;
            if (editerParentComponent instanceof JPanel){
                containerPanel = (JPanel)editerParentComponent;
            } else {
                continue;
            }

            //添加工具栏
            DefaultActionGroup actionGroup = (DefaultActionGroup)actionManager.getAction("com.linkoog.devtools.JsonEditerToolbarGroup");
            ActionToolbar actionToolbar = actionManager.createActionToolbar(ActionPlaces.TOOLBAR, actionGroup, true);
            actionToolbar.setTargetComponent(editerComponent);
            containerPanel.add(actionToolbar.getComponent(), BorderLayout.NORTH);

            // 左右分割面板
            Splitter splitter = new Splitter(false, 0.72F);
            splitter.setResizeEnabled(true);
            splitter.setDividerPositionStrategy(Splitter.DividerPositionStrategy.KEEP_SECOND_SIZE);
            splitter.setFirstComponent(editerComponent);

            Editor editor = textEditor.getEditor();
            Document document = editor.getDocument();
            String context = document.getCharsSequence().toString();
            JsonEditerRightPanel jsonEditerRightPanel = new JsonEditerRightPanel(project, textEditor);
            jsonEditerRightPanel.reset(context);
            splitter.setSecondComponent(jsonEditerRightPanel.getMyMainPanel());

            virtualFile.putUserData(KEY_JSON_EDITER_RIGHT_PANEL, jsonEditerRightPanel);
            // 处理LightVirtualFile文件，无法触发保存事件问题
            if (virtualFile instanceof LightVirtualFile){
                document.addDocumentListener(new DocumentListener() {
                    private static final long delayTime = 360;
                    private long lastUpdateTime = System.currentTimeMillis();

                    @Override
                    public void documentChanged(@NotNull DocumentEvent event) {
                        long now = System.currentTimeMillis();
                        if (now -  lastUpdateTime >=  delayTime){
                            fireContentChange(virtualFile, document.getText());
                            lastUpdateTime = now;
                        }
                    }
                });
            }

            containerPanel.add(splitter, BorderLayout.CENTER);
        }
    }

    /**
     *   文件编辑后，保存时更新右侧可视化面板
     */
    @Override
    public void after(@NotNull List<? extends @NotNull VFileEvent> events) {
        for (VFileEvent event : events) {
            if (!(event instanceof VFileContentChangeEvent)) continue;
            final VirtualFile virtualFile = event.getFile();
            if (!(virtualFile.getFileType() instanceof JsonFileType)) return;

            try {
                byte[] content = virtualFile.contentsToByteArray();
                String text = new String(content);
                fireContentChange(virtualFile, text);
            } catch (IOException ignore) {
            }
        }
    }

    private void fireContentChange(VirtualFile virtualFile, String text){
        final JsonEditerRightPanel dbTableLeftPanel = virtualFile.getUserData(KEY_JSON_EDITER_RIGHT_PANEL);
        if (dbTableLeftPanel == null) return;

        dbTableLeftPanel.reset(text);
    }



}
